package manager;

import log.Logger;
import student.Student;
import teacher.Teacher;
import java.io.*;
import java.util.*;
import teaManner.TeacherManager;
//import java.util.stream.Collectors;

public class StudentManager {
    private List<Student> students;
    private final Scanner sc;
    private final TeacherManager teacherManager; // 新增：教师管理实例

    public StudentManager() {
        students = new ArrayList<>();
        sc = new Scanner(System.in);
        teacherManager = new TeacherManager(); // 初始化教师管理实例
    }

    // 主菜单
    public void menu() {
        Logger.log("管理员用户登录");
        teacherManager.loadFromFile();
        int choice = 1;
        do {
            System.out.println("\n====== 学生管理系统 ======");
            System.out.println("1. 添加学生");
            System.out.println("2. 删除学生");
            System.out.println("3. 查找学生");
            System.out.println("4. 更新学生消息");
            System.out.println("5. 展示全部学生消息");
            System.out.println("6. 班级信息展示");
            System.out.println("7. 保存到磁盘");
            System.out.println("8. 从磁盘中加载数据");
            System.out.println("9. 数据分析");
            System.out.println("10. 按成绩排序");
            System.out.println("11. 添加教师");
            System.out.println("12. 查看所有教师");
            System.out.println("13. 删除教师");
            System.out.println("14. 分配教师给学生");
            System.out.println("0. 退出");
            System.out.println("====================================");
            System.out.print("输入你选择的功能序号: ");

            String input = sc.nextLine();
            // 验证输入是否为数字
            if (!input.matches("^\\d{1,10}$")) { // 使用正则表达式确保输入为数字
                System.out.println("输入无效！请输入数字 0-14。");
                continue; // 提示后重新输入
            }
            choice = Integer.parseInt(input);

            switch (choice) {
                case 1 -> addStudent();
                case 2 -> deleteStudent();
                case 3 -> searchStudent();
                case 4 -> updateStudent();
                case 5 -> displayAllStudents();
                case 6 -> classStatistics();
                case 7 -> saveToFile();
                case 8 -> loadFromFile();
                case 9 -> dataAnalysisMenu();
                case 10 -> sortStudentsByGrade();
                case 11 -> teacherManager.addTeacher(); // 新增：添加教师
                case 12 -> teacherManager.viewTeachers(); // 新增：查看所有教师
                case 13 -> teacherManager.deleteTeacher(); // 新增：删除教师
                case 14 -> assignTeacherToStudent(); // 新增：为学生分配教师
                case 0 -> System.out.println("Exiting...");
                default -> System.out.println("输入错误!!!!!!!!!");
            }
        } while (choice != 0);
        teacherManager.saveToFile();
    }
    // 添加学生
    private void addStudent() {
        String id = validateId(); // 判断 ID 是否合法
        System.out.print("输入 Name: ");
        String name = sc.nextLine();
        String gender = validateGender(); // 判断性别是否合法
        int age = validateAge(); // 判断年龄是否合法
        System.out.print("输入 Grade: ");
        double grade = sc.nextDouble();
        sc.nextLine(); // 清除换行符

        // 选择分配教师
        System.out.println("是否需要为该学生分配教师？(y/n)");
        String assignTeacher = sc.nextLine();
        String teacherId = null;
        if (assignTeacher.equalsIgnoreCase("y")) {
            teacherManager.viewTeachers(); // 显示所有教师
            System.out.print("输入教师 ID: ");
            teacherId = sc.nextLine();
        }

        students.add(new Student(id, name, gender, age, grade, teacherId));
        System.out.println("添加成功！！！！!");
        // 记录日志
        Logger.log("添加学生: " + id + ", 分配教师ID: " + (teacherId != null ? teacherId : "无"));
    }


    // 删除学生
    private void deleteStudent() {
        System.out.print("输入 ID: ");
        String id = sc.nextLine();
        int sz = students.size();
        students.removeIf(student -> student.getId().equals(id));//删除所有匹配的学生
        /*利用lambda表达式，接受一个student对象，并返回布尔值*/
        if (sz != students.size()) {
            System.out.println("删除成功！");
            //日志添加
            Logger.log("删除学生: ID=" + id);
        } else {
            System.out.println("删除失败，没有该学生！");
            Logger.log("删除失败: 尝试删除不存在的学生，ID=" + id);
        }
    }

    // 查询学生
    private void searchStudent() {
        System.out.print("输入 ID to search: ");
        String id = sc.nextLine();
        for (Student student : students) {
            if (student.getId().equals(id)) {
                System.out.println(student);
                Logger.log("查询学生: " + student);
                return;
            }
        }
        System.out.println("学生不存在！！!");
        Logger.log("查询失败: 学生不存在，ID=" + id);
    }
    // 更新学生信息
    private void updateStudent() {
        System.out.print("输入 ID to update: ");
        String id = sc.nextLine();
        for (Student student : students) {
            if (student.getId().equals(id)) {
                System.out.print("输入 New Name: ");
                student.setName(sc.nextLine());
                student.setGender(validateGender());
                student.setAge(validateAge());
                System.out.print("输入 New Grade: ");
                student.setGrade(sc.nextDouble());
                sc.nextLine(); // 清除换行符

                // 更新分配的教师
                System.out.println("是否需要重新分配教师？(y/n)");
                String reassignTeacher = sc.nextLine();
                if (reassignTeacher.equalsIgnoreCase("y")) {
                    teacherManager.viewTeachers();
                    System.out.print("输入教师 ID: ");
                    String teacherId = sc.nextLine();
                    student.setTeacherId(teacherId);
                }

                System.out.println("更新成功！");
                Logger.log("更新学生: " + student);
                return;
            }
        }
        System.out.println("找不到！！!");
        Logger.log("更新失败: 尝试更新不存在的学生，ID=" + id);
    }


    // 显示所有学生
    private void displayAllStudents() {
        if (students.isEmpty()) {
            System.out.println("没有学生!");
            return;
        }
        for (Student student : students) {
            Teacher teacher = teacherManager.getTeacherById(student.getTeacherId());
            String teacherName = teacher != null ? teacher.getName() : "无";
            System.out.println(student + ", 教师: " + teacherName);
        }
        Logger.log("显示所有学生");
    }


    // 班级统计信息
    //stream API操作
    private void classStatistics() {
        long totalStudents = students.size();
//        long males = 0;
//        for (Student s : students) {
//            if (s.getGender().equalsIgnoreCase("Male")) {
//                males++;
//            }
//        }
        long males = students.stream().filter(s -> s.getGender().equalsIgnoreCase("Male")).count();
        /*将students转化为管道，忽然大小写的过滤出所有男性学生*/
        long females = students.stream().filter(s -> s.getGender().equalsIgnoreCase("Female")).count();
        double averageGrade = students.stream().mapToDouble(Student::getGrade).average().orElse(0);
        /*计数平均成绩，将students转化为管道后，通过mapToDouble过滤出grade后计算平均值，如果不存在就返回0*/
        System.out.println("学生总数: " + totalStudents);
        System.out.println("男性学生数: " + males);
        System.out.println("女性学生数: " + females);
        System.out.println("平均成绩: " + averageGrade);
        Logger.log("班级数据统计");
    }

    // 保存到文件
    private void saveToFile() {
        //序列化后写入文件，student要实现Serializable接口
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("students.dat"))) {
            oos.writeObject(students);
            System.out.println("保存成功!");
            Logger.log("保存到文件");
        } catch (IOException e) {
            System.out.println("Error: " + e.getMessage());
        }
    }

    // 从文件加载
    private void loadFromFile() {
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("students.dat"))) {
            students = (List<Student>) ois.readObject();
            System.out.println("导出成功!");
            Logger.log("导出文件");
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("Error: " + e.getMessage());
        }
        /*使用try-with-resources语法自动关闭文件*/
    }

    // 数据分析 已进行功能扩展 该函数已不再使用
    private void dataAnalysis() {
        double maxGrade = students.stream().mapToDouble(Student::getGrade).max().orElse(0);//求最大成绩
        double minGrade = students.stream().mapToDouble(Student::getGrade).min().orElse(0);//求最小成绩
        //List<Student> topPerformers = students.stream().filter(s -> s.getGrade() >= maxGrade - 10).collect(Collectors.toList());
        List<Student> topPerformers = students.stream().filter(s -> s.getGrade() >= maxGrade - 10).toList();

        System.out.println("最高成绩: " + maxGrade);
        System.out.println("最低成绩: " + minGrade);
        System.out.println("优秀学生:");
        topPerformers.forEach(System.out::println);
    }

    // 按成绩排序
    private void sortStudentsByGrade() {
        if (students.isEmpty()) {
            System.out.println("没有学生!");
            return;
        }
        students.sort(Comparator.comparingDouble(Student::getGrade).reversed());//排降序
        System.out.println("学生按成绩从高到低排序:");
        students.forEach(System.out::println);
        Logger.log("按成绩排序");
    }

    // 校验 ID 是否是数字且长度为 11
    private String validateId() {
        while (true) {
            System.out.print("输入 ID (12位数字): ");
            String id = sc.nextLine();
            if (id.matches("^\\d{12}$")) {
                return id;
            }
            System.out.println("ID 必须为 12 位数字，请重新输入！");
        }
    }

    // 校验年龄是否在 18 到 24 之间
    private int validateAge() {
        while (true) {
            System.out.print("输入 Age (18-24): ");
            int age = sc.nextInt();
            sc.nextLine(); // 清除换行符
            if (age >= 18 && age <= 24) {
                return age;
            }
            System.out.println("年龄必须在 18 到 24 之间，请重新输入！");
        }
    }

    // 校验性别是否为 Male 或 Female
    private String validateGender() {
        while (true) {
            System.out.print("输入性别 (Male/Female): ");
            String gender = sc.nextLine().toLowerCase();//转小写
            if (gender.equals("male") || gender.equals("female")) {
                return gender;
            }
            System.out.println("性别必须为 Male 或 Female，请重新输入！");
        }
    }
    //普通用户进入
    public void viewOnlyMenu() {
        Logger.log("普通用户登录");
        int choice = 1;
        do {
            System.out.println("\n=== 学生信息查看系统 ===");
            System.out.println("1. 展示全部学生消息");
            System.out.println("2. 班级信息展示");
            System.out.println("3. 数据分析");
            System.out.println("0. 退出");
            System.out.println("====================================");
            System.out.print("输入你选择的功能序号: ");
            String input = sc.nextLine();
            // 验证输入是否为数字
            if (!input.matches("^\\d{1,10}$")) { // 使用正则表达式确保输入为数字
                System.out.println("输入无效！请输入数字 0-3。");
                continue; // 提示后重新输入
            }
            choice = Integer.parseInt(input);

            switch (choice) {
                case 1 -> displayAllStudents();
                case 2 -> classStatistics();
                case 3 -> dataAnalysisMenu();

                case 0 -> System.out.println("退出！");
                default -> System.out.println("输入错误！");
            }
        } while (choice != 0);
    }

    // 数据分析菜单
    private void dataAnalysisMenu() {
        Logger.log("进入数据分析菜单");
        int choice = 1;
        do {
            System.out.println("\n=== 数据分析功能 ===");
            System.out.println("1. 按性别的平均成绩");
            System.out.println("2. 成绩分布统计");
            System.out.println("3. 列出前 N 名学生");
            System.out.println("4. 列出后 N 名学生");
            System.out.println("0. 返回主菜单");
            System.out.println("====================");
            System.out.print("请输入选项：");
            String input = sc.nextLine();
            // 验证输入是否为数字
            if (!input.matches("^\\d{1,10}$")) { // 使用正则表达式确保输入为数字
                System.out.println("输入无效！请输入数字 0-3。");
                continue; // 提示后重新输入
            }
            choice = Integer.parseInt(input);

            switch (choice) {
                case 1 -> averageGradeByGender();
                case 2 -> gradeDistribution();
                case 3 -> {
                    System.out.print("请输入 N 的值：");
                    int n = sc.nextInt();
                    topStudents(n);
                }
                case 4 -> {
                    System.out.print("请输入 N 的值：");
                    int n = sc.nextInt();
                    bottomStudents(n);
                }
                case 0 -> System.out.println("返回主菜单...");
                default -> System.out.println("输入错误，请重新输入！");
            }
        } while (choice != 0);
    }
    // 按性别计算平均成绩
    private void averageGradeByGender() {
        if (students.isEmpty()) {
            System.out.println("没有学生数据！");
            return;
        }
        double totalGrade = 0.0;
        int maleCount = 0;
        for (Student s : students) {
            if (s.getGender().equalsIgnoreCase("Male")) {
                totalGrade += s.getGrade();
                maleCount++;
            }
        }
        double maleAverage = (maleCount > 0) ? (totalGrade / maleCount) : 0.0;
        totalGrade = 0.0;
        int femaleCount = 0;
        for (Student s : students) {
            if (s.getGender().equalsIgnoreCase("Female")) {
                totalGrade += s.getGrade();
                femaleCount++;
            }
        }

        double femaleAverage = (femaleCount > 0) ? (totalGrade / femaleCount) : 0.0;

        System.out.println("男性学生平均成绩: " + maleAverage);
        System.out.println("女性学生平均成绩: " + femaleAverage);
        Logger.log("按性别计算平均成绩");

    }
    // 按成绩区间统计人数
    private void gradeDistribution() {
        if (students.isEmpty()) {
            System.out.println("没有学生数据！");
            return;
        }

        long[] distribution = new long[5];
        for (Student student : students) {
            double grade = student.getGrade();
            if (grade < 60) distribution[0]++;
            else if (grade < 70) distribution[1]++;
            else if (grade < 80) distribution[2]++;
            else if (grade < 90) distribution[3]++;
            else distribution[4]++;
        }

        System.out.println("成绩分布：");
        System.out.println("0-59分: " + distribution[0] + " 人");
        System.out.println("60-69分: " + distribution[1] + " 人");
        System.out.println("70-79分: " + distribution[2] + " 人");
        System.out.println("80-89分: " + distribution[3] + " 人");
        System.out.println("90-100分: " + distribution[4] + " 人");
        Logger.log("按成绩区间统计人数");
    }
    // 列出前 N 名学生
    private void topStudents(int n) {
        if (students.isEmpty()) {
            System.out.println("没有学生数据！");
            return;
        }

        students.stream()
                .sorted(Comparator.comparingDouble(Student::getGrade).reversed())//对流中的学生对象按成绩排序，降序
                .limit(n)//提取前n个元素
                .forEach(System.out::println);//遍历提取后的学生流，然后打印到控制台
        Logger.log("排出前N位学生");
    }

    // 列出后 N 名学生
    private void bottomStudents(int n) {
        if (students.isEmpty()) {
            System.out.println("没有学生数据！");
            return;
        }
        students.stream()
                .sorted(Comparator.comparingDouble(Student::getGrade))
                .limit(n)
                .forEach(System.out::println);
        Logger.log("排出后N位学生");
    }
    // 为学生分配教师
    public void assignTeacherToStudent() {
        System.out.print("输入学生 ID: ");
        String studentId = sc.nextLine();
        System.out.print("输入教师 ID: ");
        String teacherId = sc.nextLine();

        for (Student student : students) {
            if (student.getId().equals(studentId)) {
                Teacher teacher = teacherManager.getTeacherById(teacherId);
                if (teacher != null) {
                    student.setTeacherId(teacherId);
                    System.out.println("已为学生 " + student.getName() + " 分配教师: " + teacher.getName());
                    Logger.log("为学生 " + studentId + " 分配教师: " + teacherId);
                } else {
                    System.out.println("教师 ID 无效！");
                    Logger.log("分配失败：教师 ID 无效: " + teacherId);
                }
                return;
            }
        }
        System.out.println("未找到对应的学生！");
        Logger.log("分配失败：学生 ID 无效: " + studentId);
    }

}
